<template>
  <div ref="containerRef" class="container"></div>
</template>
<script setup lang="ts">
import {
  AxesHelper,
  BoxGeometry,
  Color,
  Mesh,
  MeshLambertMaterial,
  PerspectiveCamera,
  PlaneGeometry,
  Scene,
  SphereGeometry,
  SpotLight,
  WebGLRenderer,
} from "three";
import { onMounted, ref } from "vue";
const containerRef = ref<HTMLDivElement>();

onMounted(() => {
  // 创建场景
  const scene = new Scene();
  // 创建透视相机
  // 参数：视野角度，宽高比，近平面，远平面
  const camera = new PerspectiveCamera(
    45,
    window.innerWidth / window.innerHeight,
    0.1,
    1000
  );
  // 相机位置 参数：x,y,z
  camera.position.set(-30, 40, 30);
  // 相机朝向
  camera.lookAt(scene.position);

  // 创建渲染器
  const renderer = new WebGLRenderer();
  // 设置渲染器背景颜色
  renderer.setClearColor(new Color(0xeeeeee));
  // 渲染器尺寸
  renderer.setSize(window.innerWidth, window.innerHeight);
  // ③允许在场景中使用阴影贴图
  renderer.shadowMap.enabled = true;

  // 创建坐标轴
  const axes = new AxesHelper(80);
  // 添加坐标轴到场景
  scene.add(axes);

  // 创建聚光灯 光照强度1.0
  const spotLight = new SpotLight(0xffffff, 1.0);
  // ①设置聚光灯投射阴影
  spotLight.castShadow = true;
  //设置光源不随距离衰减
  spotLight.decay = 0.0;
  // 设置聚光灯位置
  spotLight.position.set(-30, 60, -10);
  // 添加灯光到场景
  scene.add(spotLight);

  // 创建矩形平面几何体
  const planeGeometry = new PlaneGeometry(60, 20);
  // 创建网格非光泽表面的材质 可以投射阴影
  const material = new MeshLambertMaterial({ color: 0xccccff });
  // 创建网格模型
  const meshPlane = new Mesh(planeGeometry, material);
  // 设置模型位置
  meshPlane.position.set(20, 0, 0);
  // 设置模型旋转角度
  meshPlane.rotation.x = -0.5 * Math.PI;
  // ②材质是否接收阴影
  meshPlane.receiveShadow = true;
  // 添加网格模型到场景
  scene.add(meshPlane);

  // 创建立方体几何体
  const boxGeometry = new BoxGeometry(4, 4, 4);
  // 创建网格非光泽表面的材质 可以投射阴影
  const boxMaterial = new MeshLambertMaterial({
    color: 0xff0000,
    wireframe: false, // 开启线框模式
  });
  // 创建网格模型
  const boxMesh = new Mesh(boxGeometry, boxMaterial);
  // 设置模型位置
  boxMesh.position.set(2, 2, 2);
  boxMesh.castShadow = true; // ①设置模型投射阴影
  // 添加网格模型到场景
  scene.add(boxMesh);

  // 创建球体几何体
  const sphereGeometry = new SphereGeometry(4);
  // 创建网格非光泽表面的材质 可以投射阴影
  const sceneMaterial = new MeshLambertMaterial({
    color: 0x7777ff,
    wireframe: false, // 开启线框模式
  });
  // 创建网格模型
  const sphereMesh = new Mesh(sphereGeometry, sceneMaterial);
  // 设置模型位置
  sphereMesh.position.set(20, 4, 2);
  sphereMesh.castShadow = true; // ①设置模型投射阴影
  // 添加网格模型到场景
  scene.add(sphereMesh);

  // DOM挂载后添加渲染渲染器（ref 可能为空）
  containerRef.value?.appendChild(renderer.domElement);
  // 渲染场景
  renderer.render(scene, camera);
});
</script>
<style lang="scss" scoped></style>
